package com.learning.platform.service;

import com.learning.platform.dto.LearningStatsResponse;
import com.learning.platform.entity.LearningSession;
import com.learning.platform.enums.SessionType;
import com.learning.platform.repository.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 学习分析服务类
 */
@Service
@Transactional(readOnly = true)
public class LearningAnalyticsService {
    
    private final LearningSessionRepository sessionRepository;
    private final NoteRepository noteRepository;
    private final CourseRepository courseRepository;
    // TODO: 后续实现进度统计时会用到这些Repository
    @SuppressWarnings("unused")
    private final ExamRecordRepository examRecordRepository;
    @SuppressWarnings("unused")
    private final CertificateRepository certificateRepository;
    
    public LearningAnalyticsService(LearningSessionRepository sessionRepository,
                                   NoteRepository noteRepository,
                                   CourseRepository courseRepository,
                                   ExamRecordRepository examRecordRepository,
                                   CertificateRepository certificateRepository) {
        this.sessionRepository = sessionRepository;
        this.noteRepository = noteRepository;
        this.courseRepository = courseRepository;
        this.examRecordRepository = examRecordRepository;
        this.certificateRepository = certificateRepository;
    }
    
    /**
     * 获取用户学习统计数据
     */
    public LearningStatsResponse getUserLearningStats(Long userId, int days) {
        LearningStatsResponse stats = new LearningStatsResponse();
        
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusDays(days);
        
        // 基础统计
        Long totalStudyTime = sessionRepository.sumStudyTimeByUserIdAndTimeBetween(userId, startTime, endTime);
        stats.setTotalStudyTimeSeconds(totalStudyTime != null ? totalStudyTime : 0L);
        
        // 学习天数统计
        int continuousDays = (int) sessionRepository.countStudyDaysInLastNDays(userId, days);
        stats.setContinuousStudyDays(continuousDays);
        
        // 笔记统计
        long notesCount = noteRepository.countByUserIdAndCreatedAtBetween(userId, startTime, endTime);
        stats.setNotesCreated((int) notesCount);
        
        // 每日学习数据
        List<LearningStatsResponse.DailyStudyData> dailyData = getDailyStudyData(userId, days);
        stats.setDailyStudyData(dailyData);
        stats.setStudyDaysCount(dailyData.size());
        
        // 课程学习时长排行
        List<LearningStatsResponse.CourseStudyTime> courseRanking = getCourseStudyTimeRanking(userId);
        stats.setCourseRanking(courseRanking);
        stats.setCoursesStudied(courseRanking.size());
        
        // 学习类型分布
        Map<String, LearningStatsResponse.StudyTypeStats> sessionTypeStats = getSessionTypeStats(userId);
        stats.setSessionTypeStats(sessionTypeStats);
        
        // 学习热力图数据
        List<LearningStatsResponse.HourlyStudyData> hourlyData = getHourlyStudyData(userId);
        stats.setHourlyData(hourlyData);
        
        // 进度统计
        LearningStatsResponse.ProgressStats progressStats = getProgressStats(userId);
        stats.setProgressStats(progressStats);
        
        return stats;
    }
    
    /**
     * 获取每日学习数据
     */
    private List<LearningStatsResponse.DailyStudyData> getDailyStudyData(Long userId, int days) {
        LocalDateTime startDate = LocalDateTime.now().minusDays(days);
        List<Object[]> results = sessionRepository.getDailyStudyTime(userId, startDate);
        
        return results.stream()
                .map(row -> {
                    LocalDate date = ((java.sql.Date) row[0]).toLocalDate();
                    Long seconds = ((Number) row[1]).longValue();
                    return new LearningStatsResponse.DailyStudyData(date, seconds);
                })
                .collect(Collectors.toList());
    }
    
    /**
     * 获取课程学习时长排行
     */
    private List<LearningStatsResponse.CourseStudyTime> getCourseStudyTimeRanking(Long userId) {
        List<Object[]> results = sessionRepository.getCourseStudyTimeRanking(userId);
        
        return results.stream()
                .limit(10) // 只返回前10名
                .map(row -> {
                    Long courseId = ((Number) row[0]).longValue();
                    Long seconds = ((Number) row[1]).longValue();
                    
                    LearningStatsResponse.CourseStudyTime courseTime = 
                            new LearningStatsResponse.CourseStudyTime(courseId, seconds);
                    
                    // 设置课程标题
                    courseRepository.findById(courseId)
                            .ifPresent(course -> courseTime.setCourseTitle(course.getTitle()));
                    
                    return courseTime;
                })
                .collect(Collectors.toList());
    }
    
    /**
     * 获取学习类型分布统计
     */
    private Map<String, LearningStatsResponse.StudyTypeStats> getSessionTypeStats(Long userId) {
        List<Object[]> results = sessionRepository.getSessionTypeStats(userId);
        
        // 计算总时长用于计算百分比
        long totalSeconds = results.stream()
                .mapToLong(row -> ((Number) row[2]).longValue())
                .sum();
        
        Map<String, LearningStatsResponse.StudyTypeStats> statsMap = new HashMap<>();
        
        for (Object[] row : results) {
            SessionType sessionType = (SessionType) row[0];
            Long sessionCount = ((Number) row[1]).longValue();
            Long studyTimeSeconds = ((Number) row[2]).longValue();
            
            LearningStatsResponse.StudyTypeStats typeStats = 
                    new LearningStatsResponse.StudyTypeStats(
                            sessionType.getDescription(), sessionCount, studyTimeSeconds);
            
            // 计算百分比
            if (totalSeconds > 0) {
                BigDecimal percentage = BigDecimal.valueOf(studyTimeSeconds * 100.0 / totalSeconds)
                        .setScale(1, RoundingMode.HALF_UP);
                typeStats.setPercentage(percentage);
            }
            
            statsMap.put(sessionType.name(), typeStats);
        }
        
        return statsMap;
    }
    
    /**
     * 获取每小时学习数据
     */
    private List<LearningStatsResponse.HourlyStudyData> getHourlyStudyData(Long userId) {
        List<Object[]> results = sessionRepository.getStudyHeatmapData(userId);
        
        return results.stream()
                .map(row -> {
                    Integer hour = ((Number) row[0]).intValue();
                    Long sessionCount = ((Number) row[1]).longValue();
                    Long studyTimeSeconds = ((Number) row[2]).longValue();
                    
                    return new LearningStatsResponse.HourlyStudyData(hour, sessionCount, studyTimeSeconds);
                })
                .collect(Collectors.toList());
    }
    
    /**
     * 获取进度统计
     */
    private LearningStatsResponse.ProgressStats getProgressStats(Long userId) {
        LearningStatsResponse.ProgressStats progressStats = new LearningStatsResponse.ProgressStats();
        
        // TODO: 实现具体的进度统计逻辑
        // 这里需要根据实际的数据模型来计算
        // 例如：已完成的课程数、章节数、考试数等
        
        progressStats.setTotalLessonsEnrolled(0);
        progressStats.setLessonsCompleted(0);
        progressStats.setOverallProgressPercentage(BigDecimal.ZERO);
        progressStats.setCoursesCompleted(0);
        progressStats.setExamsCompleted(0);
        progressStats.setCertificatesEarned(0);
        
        return progressStats;
    }
    
    /**
     * 开始学习会话
     */
    @Transactional
    public LearningSession startLearningSession(Long userId, Long courseId, Long lessonId, SessionType sessionType) {
        // 结束之前未结束的会话
        List<LearningSession> activeSessions = sessionRepository.findByUserIdAndEndTimeIsNullOrderByStartTimeDesc(userId);
        for (LearningSession session : activeSessions) {
            session.endSession();
            sessionRepository.save(session);
        }
        
        // 创建新的学习会话
        LearningSession newSession = new LearningSession(userId, courseId, lessonId, sessionType);
        return sessionRepository.save(newSession);
    }
    
    /**
     * 结束学习会话
     */
    @Transactional
    public void endLearningSession(Long sessionId, BigDecimal progressPercentage) {
        LearningSession session = sessionRepository.findById(sessionId)
                .orElseThrow(() -> new RuntimeException("学习会话不存在"));
        
        session.endSession();
        if (progressPercentage != null) {
            session.updateProgress(progressPercentage);
        }
        
        sessionRepository.save(session);
    }
    
    /**
     * 更新学习进度
     */
    @Transactional
    public void updateLearningProgress(Long sessionId, BigDecimal progressPercentage) {
        LearningSession session = sessionRepository.findById(sessionId)
                .orElseThrow(() -> new RuntimeException("学习会话不存在"));
        
        session.updateProgress(progressPercentage);
        sessionRepository.save(session);
    }
    
    /**
     * 获取用户当前活跃的学习会话
     */
    public Optional<LearningSession> getActiveSession(Long userId) {
        List<LearningSession> activeSessions = sessionRepository.findByUserIdAndEndTimeIsNullOrderByStartTimeDesc(userId);
        return activeSessions.isEmpty() ? Optional.empty() : Optional.of(activeSessions.get(0));
    }
}
